package io.shallwe._admin.line;

import cn.hutool.core.date.DateTime;
import com.beust.jcommander.internal.Sets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.ehcache.CacheKit;
import io.shallwe._admin.basedata.hangerframe.HangerFrameService;
import io.shallwe._admin.basedata.init.StaticHangerService;
import io.shallwe._admin.basedata.init.StaticMapService;
import io.shallwe.common.model.*;
import io.shallwe.common.model.Scanner;
import io.shallwe.history.ParameterCurveService;
import io.shallwe.history.LogTocService;
import io.shallwe.scanner.log.ScannerRecordService;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : 王小伟
 * @date : 2019-07-24 00:37:52
 */
public class LocationService {

    @Inject
    ScannerRecordService scannerRecordService;

    @Inject
    StaticMapService staticMapService;

    @Inject
    LineInfoService lineInfoService;

    @Inject
    io.shallwe._admin.basedata.location.LocationService locationService;



    @Inject
    HangerFrameService hangerFrameService;
    @Inject
    LogTocService logTocService ;
    @Inject
    ParameterCurveService parameterCurveService;


    @Inject
    ExitScanService exitScanService;
    @Inject
    EnterScanService enterScanService;
    private EnterBuffer enterBufferDao= new EnterBuffer().dao();


    /**
     * 更新产线信息
     */
    public void  doUpdateLineInfo(){
        //更新enter_scan到buffer
        Date currentTime = new Date();
        List<EnterScan> enterScans = enterScanService.listAllValidScanData();
        for (EnterScan enterScan : enterScans) {
            if(enterScan.getMaterialCount()>0){
                enterScanService.hangerMoveToBuffer(enterScan);
            }
        }

        //查询当前所有产线工位的信息
        List<LineInfo> currentLineInfoList = lineInfoService.listAllLineInfo();
        //清除过期缓冲数据
        List<EnterBuffer> enterBuffers = enterScanService.listAllValidBufferData();
        Map<String, LineInfo> lineInfoMap =
                currentLineInfoList.stream().collect(Collectors.toMap(lineInfo -> lineInfo.getHangerNo(),
                        lineInfo -> lineInfo));

        for (EnterBuffer enterBuffer : enterBuffers) {
            String hangerNo = enterBuffer.getHangerNo();
            if(lineInfoMap.containsKey(hangerNo)){
                LineInfo lineInfo = lineInfoMap.get(hangerNo);
                int sort =lineInfo.getSort();

                long bufferUpdateTime = enterBuffer.getUpdateTime().getTime() + 60000;
                long lineInfoUpdate = lineInfo.getLocationEnterTime().getTime();
                if(bufferUpdateTime < lineInfoUpdate && sort>3 && sort<190){
                    enterBuffer.setStatusFlag(3).setUpdateTime(new Date()).update();
                }
            }
        }

        //更新exit_scan到周转车信息
        List<ExitScan> exitScans = exitScanService.listAllValidScanData();
        for (ExitScan exitScan : exitScans) {
            if(StrKit.isBlank(exitScan.getBarcode())==false && StrKit.isBlank(exitScan.getVehicleNo())==false){
                exitScanService.updateVehicleInfo(exitScan);
            }
        }

        //清除过期下线缓冲区数据
        List<ExitBuffer> exitBuffers = exitScanService.listAllValidBufferData();
        for (ExitBuffer exitBuffer : exitBuffers) {
            String hangerNo = exitBuffer.getHangerNo();
            if(lineInfoMap.containsKey(hangerNo)){
                LineInfo lineInfo = lineInfoMap.get(hangerNo);
                int sort =lineInfo.getSort();
                long bufferUpdateTime = exitBuffer.getUpdateTime().getTime() + 60000;
                long lineInfoUpdate = lineInfo.getLocationEnterTime().getTime();
                if(bufferUpdateTime < lineInfoUpdate && (sort>190||sort<184)){
                    exitBuffer.setStatusFlag(3).setUpdateTime(new Date()).update();
                }
            }
        }

        ScannerRecord headScannerRecord = scannerRecordService.getHeadScannerRecord();
        if(headScannerRecord==null){
            return;
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LogKit.warn("扫描到条码："+ headScannerRecord.toJson());


        Set<String> hangerNoSets =lineInfoMap.keySet();
        //获取自动上线的条码
        String onLineHangerNo = headScannerRecord.getHangerNo();
        if(hangerNoSets.contains(onLineHangerNo)==false){
            headScannerRecord.setUpdateTime(currentTime).setStatusFlag(ScannerRecord.FINISH).update();
            return;
        }
        //检测到自动上线扫描记录
        if(headScannerRecord.getScannerType()== Scanner.AUTO_ENTER){
            //查询扫描后所有挂具对应的工位信息
            Map<String, String> nextHangerLocationMap = hangerFrameService.getHangerLocationMap(onLineHangerNo);
            List<LocationDetail>  locationDetails = Lists.newLinkedList();
            //工位对应采集参数表
            Map<String, List<Toc>> locationParameterConfigMap = logTocService.getLocationParameterConfigMap();
            Map<String, Location> locationMap = locationService.getLocationMap();
            for (LineInfo lineInfo : currentLineInfoList) {
                String hangerNo = lineInfo.getHangerNo();
                if(StrKit.isBlank(hangerNo)){
                    continue;
                }
                if(nextHangerLocationMap.containsKey(hangerNo)){
                    String nextLocation = nextHangerLocationMap.get(hangerNo);
                    String currentLocation = lineInfo.getLocationCode();
                    //如果当前工位和接下来的工位不同，则表明挂具离开旧的工位，来到新的工位
                    if(StrKit.equals(nextLocation,currentLocation)==false){
                        //更新工位情况和时间信息
                        lineInfo.setLastLocationCode(currentLocation).setLocationCode(nextLocation);
                        Date locationEnterTime = lineInfo.getLocationEnterTime();
                        if(StrKit.isBlank(currentLocation)){
                            lineInfo.setLocationStatus(LineInfo.ENTER_NEW_LOCATION);
                        }else{
                            lineInfo.setLocationStatus(LineInfo.LEAVE_OLD_LOCATION_AND_ENTER_NEW_LOCATION);
                            LocationDetail detail = new LocationDetail();
                            detail.setHangerNo(hangerNo);
                            detail.setLocationCode(currentLocation);
                            detail.setStartTime(locationEnterTime);
                            detail.setEndTime(currentTime);

                            if(locationMap.containsKey(currentLocation)){
                                Location location = locationMap.get(currentLocation);
                                detail.setStayTimeControlFlag(location.getControlFlag());
                                detail.setMaxStayTime(location.getMaxStayTime());
                                detail.setMinStayTime(location.getMinStayTime());
                            }
                            copyFieldFromLineInfoToDetail(lineInfo, detail);

                            if(locationParameterConfigMap.containsKey(currentLocation)){
                                List<Toc> tocList = locationParameterConfigMap.get(currentLocation);
                                for (Toc toc : tocList) {
                                    String startTime =formatter.format(locationEnterTime);
                                    String endTime = formatter.format(currentTime);
                                    createLocationParameterDetail(locationDetails, detail,toc,startTime,endTime);
                                }
                            }
                        }
                        lineInfo.setLocationEnterTime(currentTime);
                    }else {
                        lineInfo.setLocationStatus(LineInfo.KEEP_STAY_IN_OLD_LOCATION);
                    }
                }
            }

            //保存工位详情信息
            if(locationDetails.size()>0) {
                Db.use("pg").batchSave(locationDetails, locationDetails.size());
            }

            //更新缓冲区信息到产线信息表
            EnterBuffer buffer = enterBufferDao.template("enterBuffer.getByHangerNoFromBuffer",onLineHangerNo).findFirst();
            int indexNo = hangerFrameService.getIdByHangerNo(onLineHangerNo);
            int[] sorts = staticMapService.listHangerSortByScannerCode(indexNo);
            Map<Integer, Integer> sortMap = Maps.newHashMap();
            int length = sorts.length;
            for (int index =0;index<length;index++){
                int id =index+1;
                int sort = sorts[index];
                sortMap.put(id,sort);
            }
            //更新缓冲到产线
            if(buffer!=null) {
                ////清除上线缓冲
                buffer.setUpdateTime(new Date()).setStatusFlag(2).update();
                //更新所有工位的挂具信息
                for (LineInfo lineInfo : currentLineInfoList) {
                    if (StrKit.equals(buffer.getHangerNo(), lineInfo.getHangerNo())) {
                        if (StrKit.notBlank(buffer.getBarcode())) {
                            lineInfo.setBarcode(buffer.getBarcode());
                        }
                        if (StrKit.notBlank(buffer.getMaterialNo())) {
                            lineInfo.setMaterialNo(buffer.getMaterialNo());
                        }
                        if (StrKit.notBlank(buffer.getTraceNo())) {
                            lineInfo.setTraceNo(buffer.getTraceNo());
                        }
                        if (buffer.getMaterialCount() > 0) {
                            lineInfo.setMaterialCount(buffer.getMaterialCount());
                        }
                        if (StrKit.notBlank(buffer.getAccountId())) {
                            lineInfo.setAccountId(buffer.getAccountId());
                        }
                        break;
                    }
                }
            }
            //板链前移
            for (LineInfo lineInfo : currentLineInfoList) {
                String hangerNo = lineInfo.getHangerNo();
                Integer id = hangerFrameService.getIdByHangerNo(hangerNo);
                if (sortMap.containsKey(id)) {
                    int sort = sortMap.get(id);
                    lineInfo.setSort(sort).setUpdateTime(new Date());
                }
                lineInfo.setUpdateTime(currentTime);
            }
            //更新工位信息
            lineInfoService.updateAllLineInfo(currentLineInfoList);
        }

        if(headScannerRecord.getScannerType()== Scanner.AUTO_EXIT){
            String offLineHangerNo = headScannerRecord.getHangerNo();
            if(hangerNoSets.contains(offLineHangerNo)) {
                exitScanService.doAutoScan(offLineHangerNo);
                CacheKit.remove("listLineInfo", "all");
            }
        }
        headScannerRecord.setUpdateTime(currentTime).setStatusFlag(ScannerRecord.FINISH).update();
    }

    /**
     *     创建工位工艺参数详细信息
     *     在这个工位的时间内参数的最大值、最小值
     *     参数设定的最大值、最小值
     */
    private void createLocationParameterDetail( List<LocationDetail> locationDetails, LocationDetail detail,Toc toc,String startTime,String endTime) {
        Record parameterSummaryData = parameterCurveService.getParameterSummaryData(toc.getTableName(), startTime, endTime);
        if(parameterSummaryData!=null){
            LocationDetail locationDetailParams= new LocationDetail();
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            locationDetailParams.setUpdateTime(new Date());
            locationDetailParams._setAttrs(detail);
            locationDetailParams.setParameterAddress(toc.getAddress());

            //记录参数设定的最大最小值、是否启用
            locationDetailParams.setParameterMaxValueConfig(toc.getParameterMaxValue());
            locationDetailParams.setParameterMinValueConfig(toc.getParameterMinValue());
            locationDetailParams.setParameterControlFlag(toc.getControlFlag());

            locationDetailParams.setParameterName(toc.getRemark());
            locationDetailParams.setParameterMaxValue(parameterSummaryData.getFloat("parametermaxvalue"));
            locationDetailParams.setParameterMinValue(parameterSummaryData.getFloat("parameterminvalue"));
            locationDetails.add(locationDetailParams);
        }
    }

    private void copyFieldFromLineInfoToDetail(LineInfo lineInfo, LocationDetail detail) {
        detail.setStartTime(lineInfo.getLocationEnterTime());
        detail.setLocationCode(lineInfo.getLocationCode());
        String traceNo = lineInfo.getTraceNo();
        detail.setTraceNo(traceNo==null? "":traceNo);

        String barcode = lineInfo.getBarcode();
        detail.setBarcode(barcode==null? "":barcode);

        String frameNo = lineInfo.getFrameNo();
        detail.setFrameNo(frameNo==null?"":frameNo);

        String materialNo = lineInfo.getMaterialNo();
        detail.setMaterialNo(materialNo==null?"":materialNo);

        Integer materialCount = lineInfo.getMaterialCount();
        detail.setMaterialCount(materialCount==null?0:materialCount);
    }
}
